/*
 * @Author: xiaosihan
 * @Date: 2021-05-03 19:37:41
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-11-07 16:38:32
 */

import React from "react";
import * as THREE from "three";
import { WebGLRenderTarget } from "three";
import Group3D from "../Group3D/Group3D";
import Object3D from "../Object3D/Object3D";
import Object3DComponent, { Object3DComponentProps } from "../Object3D/Object3DComponent";
import Transition from "../xrt_util/Transition";
import TransitionColor from "../xrt_util/TransitionColor";
import xrt_util from "../xrt_util/xrt_util";
import CircleLight from "./CircleLight";
import Cylinder from "./cylinder/Cylinder";
import LightBaffles from "./lightBaffle/LightBaffles";
import VolumeLight from "./volumeLight/VolumeLight";



export interface SpotLightProps extends Object3DComponentProps {

    castShadow: boolean, // 创建阴影
    color: string, // 光照的颜色
    intensity: number, // 光照强度
    angle: number, //散开角度
    penumbra: number, // 衍射程度
    decay: number, // 衰减程度
    distance: number // 照射距离
    shadowResolution?: number // 阴影分辨率
}

interface State {
}

export default class SpotLight extends Object3DComponent<SpotLightProps, State> {
    constructor(props: SpotLightProps) {
        super(props);

        this.object3d.add(this.spotLight);

        this.spotLight.target.position.z = 1;// 照射目标
        this.spotLight.target.matrixAutoUpdate = false;
        this.spotLight.target.updateMatrix();
        this.spotLight.add(this.spotLight.target);
    }

    static defaultProps = {
        castShadow: false, // 创建阴影
        color: "#ffffff", // 光照的颜色
        intensity: 1, // 光照强度
        angle: Math.PI / 4, //散开角度
        penumbra: 0.2, // 衍射程度
        decay: 1, // 衰减程度
        distance: 100, // 照射距离
        shadowResolution: 512 // 阴影分辨率
    }

    spotLight = new THREE.SpotLight() as unknown as THREE.SpotLight & Object3D;

    // 颜色缓动对象
    Tcolor = new TransitionColor(this.props.color || "#fff");

    // 灯光参数
    lightParams = new Transition();

    componentBeforeRender() {
        let keepRun = this.setLightParam();
        return keepRun;
    }

    // 设置灯光的参数
    setLightParam() {
        let keepRun = false;

        if (!this.Tcolor.isDone()) {
            const { r, g, b } = this.Tcolor.getJson();
            this.spotLight.color.setRGB(r, g, b);
            keepRun = true;
        }

        if (!this.lightParams.isDone()) {
            const { angle, intensity, penumbra, decay, distance } = this.lightParams.getJson();

            Object.assign(this.spotLight, {
                angle,
                intensity,
                penumbra,
                decay,
                distance
            });
            keepRun = true;
        }

        return keepRun;
    }

    // 设置灯光的过渡参数
    setLightTansParam() {
        const {
            bezier,
            duration = 500,
            castShadow = false, // 创建阴影
            color = "#ffffff", // 光照的颜色
            intensity = 1, // 光照强度
            angle = 45, //散开角度
            penumbra = 0.2, // 衍射程度
            decay = 1, // 衰减程度
            distance = 100, // 照射距离
            shadowResolution = 512 // 阴影分辨率
        } = this.props;

        this.Tcolor.setBezier(bezier).setDuration(duration).set(color);

        this.lightParams.setBezier(bezier).setDuration(duration).set({ intensity, penumbra, angle, decay, distance });

        this.spotLight.castShadow = castShadow;

        // 分辨率直接赋值 不能有缓动效果
        this.spotLight.shadow.mapSize.set(shadowResolution, shadowResolution);

        if (this.spotLight.shadow.map) {
            (this.spotLight.shadow.map as WebGLRenderTarget).setSize(shadowResolution, shadowResolution);
        }
    }

    componentDidMount() {
        // 减少双面物体的自阴影
        this.spotLight.shadow.normalBias = -0.05;

        this.setLightTansParam();
        this.setLightParam();
    }

    componentDidUpdate() {
        this.setLightTansParam();
    }

    render() {

        const { dev } = this.context;

        if (!dev) {
            return null;
        }

        const { color } = this.props;

        return (
            <Group3D
                rotation={{ x: Math.PI / -2 }}
            >
                {/* 灯筒 */}
                <Cylinder
                    cursor="pointer"
                    onMouseenter={() => {
                        if (!xrt_util.isReactDev()) {
                            this.setState({ hover: true });
                        }
                    }}
                    onMouseleave={() => {
                        this.setState({ hover: false })
                    }}
                />

                {/* 灯罩 */}
                <LightBaffles />

                <CircleLight
                    color={color}
                    rotation={{ x: Math.PI / 2 }}
                    position={{ x: 0, y: -1.01, z: 0 }}
                />

                {/* 体积光1 */}
                <VolumeLight
                    side={THREE.BackSide}
                    color={color}
                    alphaTest={0.1}
                    position={{ x: 0, y: -2.01, z: 0 }}
                    cursor="pointer"
                    title={
                        <span
                            style={{
                                position: "relative",
                                backgroundColor: "rgba(0, 0, 0, 0.8)",
                                borderRadius: 4,
                                padding: "4px 8px",
                                color: "#fff"
                            }}
                        >
                            {"聚光灯<SpotLight/>"}
                        </span>
                    }
                />

                {/* 体积光2 */}
                <VolumeLight
                    side={THREE.FrontSide}
                    color={color}
                    alphaTest={0.1}
                    position={{ x: 0, y: -2.01, z: 0 }}
                />

            </Group3D>
        );
    }
}